package com.gugee.ins.common.dal.ai;

import com.gugee.common.exception.BizException;
import com.gugee.ins.common.constant.AiConst;
import com.gugee.ins.common.dal.ai.config.AiAnalysisConfig;
import com.gugee.ins.common.model.ai.*;
import com.xiguaji.boot.retry.RetryableException;
import com.xiguaji.boot.toolkit.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ai 分析
 * @author Huangxin
 */
@Component
public class AiAnalysisClient {

    /**
     * header
     */
    private static final String ACCEPT = "Accept";

    /**
     * biz error enum
     */
    private static final String BIZ_AI_STATUS_ERROR = "BIZ_AI_STATUS_ERROR";

    /**
     *
     */
    @Autowired
    AiAnalysisConfig aiAnalysisConfig;

    /**
     *
     */
    @Autowired
    RestTemplate restTemplate;

    /**
     * 人脸识别接口
     * @param uid 博主id
     * @param picUrl 图片url
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisAvatar.retry:1}")
    public FaceRecognition getFaceRecognitionByPicUrl(Long uid, String picUrl) {
        String uri = aiAnalysisConfig.getHost() + "/facedetact";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
        Map<String,Object> map = new HashMap<>(2);
        Map<String,Object> uidToUrl = new HashMap<>(2);
        uidToUrl.put("uid",uid);
        uidToUrl.put("url",picUrl);
        map.put("uidtourl",uidToUrl);
        map.put("needrace",1);
        HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(map),headers);

        ResponseEntity<FaceRecognition> responseEntity = restTemplate.postForEntity(uri,request,FaceRecognition.class);
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new BizException(String.format("get FaceRecognition error. status: %s . msg: %s",
                    responseEntity.getStatusCodeValue(), responseEntity.getBody()), BIZ_AI_STATUS_ERROR);
        }
        if (responseEntity.getBody() == null) {
            throw new RetryableException("get FaceRecognition error, retry times " + aiAnalysisConfig.getAnalysisAvatarRetryTimes()
                    + ". uid:" + uid + " , url:" + picUrl);
        }
        return responseEntity.getBody();
    }

    /**
     * 语言识别
     * @param aiAnalysisMap
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisLanguage.retry:1}")
    public Map<String,String> getLanguageByText(Map<String,String> aiAnalysisMap) {
        if(aiAnalysisMap!= null && !aiAnalysisMap.isEmpty()){
            String uri = aiAnalysisConfig.getHost() + "/getlangtype";

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
            Map<String,Map<String,String>> map = new HashMap<>(1);
            map.put("content",aiAnalysisMap);
            HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(map),headers);

            ResponseEntity<Map<String,String>> responseEntity = restTemplate.exchange(uri, HttpMethod.POST, request,
                    new ParameterizedTypeReference<Map<String,String>>() {});
            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                throw new BizException(String.format("get FaceRecognition error. status: %s . msg: %s",
                        responseEntity.getStatusCodeValue(), responseEntity.getBody()),  BIZ_AI_STATUS_ERROR);
            }
            if (responseEntity.getBody() == null || responseEntity.getBody().isEmpty()) {
                throw new RetryableException("get Language error, retry times " + aiAnalysisConfig.getAnalysisLanguageRetryTimes());
            }
            return responseEntity.getBody();
        }
        return new HashMap<>(1);
    }

    /**
     * 收入接口
     * @param inComeRequestList
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisInCome.retry:1}")
    public List<InComeResponse> getIncome(List<InComeRequest> inComeRequestList) {
        if(inComeRequestList == null || inComeRequestList.isEmpty()){
            return new ArrayList<>();
        }
        String uri = aiAnalysisConfig.getHost() + "/incomeforecas";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
        Map<String,Object> map = new HashMap<>(1);
        map.put("data",inComeRequestList);
        HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(map),headers);

        ResponseEntity<List<InComeResponse>> responseEntity = restTemplate.exchange(uri, HttpMethod.POST, request,
                new ParameterizedTypeReference<List<InComeResponse>>() {});
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new BizException(String.format("get InCome error. status: %s . msg: %s",
                    responseEntity.getStatusCodeValue(), responseEntity.getBody()),  BIZ_AI_STATUS_ERROR);
        }
        if (responseEntity.getBody() == null) {
            throw new RetryableException("get InCome error, retry times " + aiAnalysisConfig.getAnalysisInComeRetryTimes());
        }
        return responseEntity.getBody();
    }

    /**
     * 达人分类识别
     * @param insBloggerMediaTags
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisCategory.retry:1}")
    public InsBloggerCategoryResponse getCategoryByText(List<InsBloggerMediaTag> insBloggerMediaTags) {
        if(insBloggerMediaTags!= null && !insBloggerMediaTags.isEmpty()){
            String uri = aiAnalysisConfig.getHost() + "/gettalentcls";

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
            Map<String,List<InsBloggerMediaTag>> map = new HashMap<>(1);
            map.put("data",insBloggerMediaTags);
            HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(map),headers);

            ResponseEntity<InsBloggerCategoryResponse> responseEntity = restTemplate.postForEntity(uri,request,InsBloggerCategoryResponse.class);
            if (responseEntity.getStatusCode() != HttpStatus.OK ) {
                throw new BizException(String.format("ai Analysis get Category error. status: %s . msg: %s",
                        responseEntity.getStatusCodeValue(), responseEntity.getBody()),  BIZ_AI_STATUS_ERROR);
            }
            if (responseEntity.getBody() == null || responseEntity.getBody().getStatus() == AiConst.AI_STATUS_FAIL) {
                throw new RetryableException("ai Analysis get Category error, retry times " + aiAnalysisConfig.getAnalysisCategoryRetryTimes());
            }
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 品牌分析
     * @param content
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisBrand.retry:1}")
    public InsBloggerBrandResponse getBrandByText(String content) {
        if(!StringUtils.isEmpty(content)){
            String uri = aiAnalysisConfig.getAiBrandHost() + "/getbrandinfoforins";

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
            Map<String,String> map = new HashMap<>(1);
            map.put("content",content);
            HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(map),headers);

            ResponseEntity<InsBloggerBrandResponse> responseEntity = restTemplate.postForEntity(uri,request,InsBloggerBrandResponse.class);
            if (responseEntity.getStatusCode() != HttpStatus.OK ) {
                throw new BizException(String.format("ai Analysis get Brand error. status: %s . msg: %s",
                        responseEntity.getStatusCodeValue(), responseEntity.getBody()),  BIZ_AI_STATUS_ERROR);
            }
            if (responseEntity.getBody() == null) {
                throw new RetryableException("ai Analysis get Brand error, retry times " + aiAnalysisConfig.getAnalysisBrandRetryTimes());
            }
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 商品分类分析
     * @param insProductCategoryRequest
     * @return
     */
    @Retryable(value = RetryableException.class, maxAttemptsExpression = "${ins.ai.analysisProductCategory.retry:1}")
    public InsProductCategoryResponse getProductCategory(InsProductCategoryRequest insProductCategoryRequest) {
        String uri = aiAnalysisConfig.getHost() + "/getgoodscateforins";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> request = new HttpEntity<>(JsonUtil.parseJson(insProductCategoryRequest),headers);

        ResponseEntity<InsProductCategoryResponse> responseEntity = restTemplate.postForEntity(uri,request,InsProductCategoryResponse.class);
        if (responseEntity.getStatusCode() != HttpStatus.OK ) {
            throw new BizException(String.format("ai Analysis get Product Category error. status: %s . msg: %s",
                    responseEntity.getStatusCodeValue(), responseEntity.getBody()),  BIZ_AI_STATUS_ERROR);
        }
        if (responseEntity.getBody() == null) {
            throw new RetryableException("ai Analysis get Product Category error, retry times " + aiAnalysisConfig.getAnalysisBrandRetryTimes());
        }
        return responseEntity.getBody();

    }
}
